package com.youboy.wechatapi.service.message.impl;

import static org.elasticsearch.index.query.QueryBuilders.rangeQuery;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.elasticsearch.index.query.BoolFilterBuilder;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.FilterBuilders;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.youboy.searchapi.api.CompanyService;
import com.youboy.searchapi.api.ProductService;
import com.youboy.searchapi.domain.Company;
import com.youboy.searchapi.domain.Product;
import com.youboy.searchapi.domain.Product.Fields;
import com.youboy.wechatapi.domain.enums.SearchType;
import com.youboy.wechatapi.domain.message.Article;
import com.youboy.wechatapi.domain.message.NewsMessage;
import com.youboy.wechatapi.domain.message.TextMessage;
import com.youboy.wechatapi.domain.mysql.BindInfo;
import com.youboy.wechatapi.domain.mysql.Feedback;
import com.youboy.wechatapi.domain.mysql.SearchInfo;
import com.youboy.wechatapi.repository.message.BindRepository;
import com.youboy.wechatapi.repository.message.FeedbackRepository;
import com.youboy.wechatapi.repository.message.SearchRepository;
import com.youboy.wechatapi.service.message.MsgTextService;
import com.youboy.wechatapi.utils.kwfilter.KeyWord;
import com.youboy.wechatapi.utils.kwfilter.TextFilter;
import com.youboy.wechatapi.utils.text.MsgUtils;
import com.youboy.wechatapi.utils.wechat.MessageUtil;

/**
 * @ProjectName：wechatapi
 * @author：冉尧（Yvan）
 * @CreateTime：2014年9月29日 下午1:53:57
 * @Remarks：
 */
@Service
public class MsgTextServiceImpl implements MsgTextService {

	private Logger log = Logger.getLogger(MsgTextServiceImpl.class);
	
	//微商铺地址
	@Value(value = "${wechat.shop.url}")
	private String wechatShopUrl;
	
	@Value(value = "${bind.index.url}")
	private String bindIndexUrl;
	
	@Value(value = "${wechatapi.url}")
	private String wechatapiUrl;

	@Autowired
	private ProductService productService;

	@Autowired
	private CompanyService companyService;

	@Autowired
	private FeedbackRepository feedbackRepository;

	@Autowired
	private BindRepository bindRepository;
	
	@Autowired
	private SearchRepository searchRepository;
	
	private KeyWord kwf = KeyWord.getInstance();

	public String receiveMsgText(String fromUserName, String toUserName,
			String content) throws Exception {

		// 接收用户发送的文本消息内容
		// String content = requestMap.get("Content");

		String respMessage = null;

		// 默认回复此文本消息
		TextMessage textMessage = new TextMessage();
		textMessage.setFromUserName(toUserName);
		textMessage.setToUserName(fromUserName);
		textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);

		if (StringUtils.isBlank(content)) {
			log.info("content is null !");
			return this.setMsg(fromUserName, toUserName);
		}

		content = content.trim();
		
		log.info("this content is [" + content + "].");
		
		List<Article> recruitmentInfo = MsgUtils.activeMap.get(content.toLowerCase());
		if(recruitmentInfo != null && recruitmentInfo.size() > 0){
			// 创建图文消息
			NewsMessage newsMessage = new NewsMessage();
			newsMessage.setToUserName(fromUserName);
			newsMessage.setFromUserName(toUserName);
			newsMessage.setCreateTime(new Date().getTime());
			newsMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_NEWS);
			// newsMessage.setFuncFlag(0);
			newsMessage.setArticleCount(recruitmentInfo.size());
			newsMessage.setArticles(recruitmentInfo);

			respMessage = MessageUtil.newsMessageToXml(newsMessage);
			
			//保存搜索信息
			SearchType searchType = MsgUtils.searchTypeMap.get(content);
			this.saveSearchInfo(searchType, fromUserName, content, content);
			return respMessage;
		}
		
		if(content.equalsIgnoreCase("help") || content.equalsIgnoreCase("?")
				|| content.equalsIgnoreCase("求助") ||  content.equalsIgnoreCase("帮助")
				|| content.equalsIgnoreCase("？")){
			String textResult = this.getHelpMsg(false, fromUserName);
			textMessage.setContent(textResult);
			respMessage = MessageUtil.textMessageToXml(textMessage);
			return respMessage;
		}
		
		String textResult = MsgUtils.msgMap.get(content.toLowerCase());
		if(StringUtils.isNotBlank(textResult)){
			textMessage.setContent(textResult);
			respMessage = MessageUtil.textMessageToXml(textMessage);
			log.info("[" + content + "] get msgMap success !"); //, the textMessage is 【" + textResult + "】
			return respMessage;
		}

		String msg = content;
		String msg3 = content;
		
		int prefixLength = 2;
		int prefix2Length = 3;
		
		if (content.length() > prefixLength) {
			msg = content.substring(0, prefixLength).trim();
		}
		
		if (msg3.length() > prefix2Length) {
			msg3 = content.substring(0, prefix2Length).trim();
		}
		
		//log.info(msg + "       " + msg3);
		
		if (msg.equals("投诉") || msg.equals("问题")) {
			textResult = MsgUtils.msgMap.get(msg + "deal");
			textMessage.setContent(textResult);
			respMessage = MessageUtil.textMessageToXml(textMessage);

			Feedback feddback = new Feedback(1, fromUserName, content, new Date());
			feedbackRepository.save(feddback);
		} else if (msg.equals("意见") || msg.equals("建议") || msg.equals("反馈")) {
			textResult = MsgUtils.msgMap.get(msg + "deal");
			textMessage.setContent(textResult);
			respMessage = MessageUtil.textMessageToXml(textMessage);

			Feedback feddback = new Feedback(2, fromUserName, content, new Date());
			feedbackRepository.save(feddback);
		} else if (msg.equals("商铺") || msg.equals("公司") || msg.equals("商家")) {

			respMessage = this.getCompanyInfo(fromUserName, toUserName, msg, content);
			
		} else if(msg3.equals("供应商") || msg3.equals("采购商")){

			respMessage = this.getCompanyInfo(fromUserName, toUserName,msg3 , content);
			
		} else if (msg.equals("产品") || msg.equals("商品")) {
			
			respMessage = this.getProductInfo(fromUserName, toUserName, msg, content);
			
		} else {
			
			respMessage = this.getProductInfo(fromUserName, toUserName, "", content);
		}

		return respMessage;
	}
	
	/**
	 * 根据是否绑定获取相应帮助信息
	 * @param fromUserName
	 * @param toUserName
	 * @return
	 * @throws UnsupportedEncodingException 
	 */
	public String getHelpMsg(Boolean isInput, String fromUserName) throws UnsupportedEncodingException{
		
		BindInfo bind = null;
		boolean isBind = false; 
		try {
			bind = bindRepository.getBindInfo(fromUserName);
		} catch (Exception e) {
			log.error("[openid:" + fromUserName + "] get bindinfo error !", e);
		}

		if(bind != null){
			isBind = true;
		}
		
		String bindUrl = null;
		bindUrl = bindIndexUrl.replace("OPENID", fromUserName);
		/*if (bind == null) {
		} else {
			bindUrl = wechatShopUrl.replace("USERNAME", bind.getUsername().toLowerCase());
			bindUrl = this.setCallBackUrl(fromUserName, bindUrl);
		}*/
		String helpMsg = MsgUtils.getHelpMsg(isInput, isBind, fromUserName, bindUrl);
		return helpMsg;
	}
	
	public String setMsg(String fromUserName, String toUserName) throws UnsupportedEncodingException{
		String helpMsg = this.getHelpMsg(true, fromUserName);
		TextMessage textMessage = new TextMessage();
		textMessage.setFromUserName(toUserName);
		textMessage.setToUserName(fromUserName);
		textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);
		textMessage.setContent(helpMsg);
		String respMessage = MessageUtil.textMessageToXml(textMessage);
		return respMessage;
	}

	/**
	 * 获取产品信息
	 * 
	 * @param fromUserName
	 * @param toUserName
	 * @param content
	 * @return
	 * @throws UnsupportedEncodingException 
	 */
	private String getProductInfo(String fromUserName, String toUserName,
			String key, String content) throws UnsupportedEncodingException {
		//过滤特殊符号
		content = TextFilter.StringFilter(content);
		
		//
		String keyword = content.replaceFirst(key, "").trim();
		// 过滤关键词
		keyword = kwf.filter_out(keyword, "0", keyword);
		

		if (StringUtils.isBlank(keyword)) {
			log.error("keyword is null! ");
			return this.setMsg(fromUserName, toUserName);
		}

		BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
		// 根据关键词获取
		boolQuery.must(QueryBuilders.fieldQuery("title","\"" + keyword + "\"").boost(2.4f));
		boolQuery.should(rangeQuery(Fields.sort).lt(999999).boost(5.5f));
		boolQuery.should(QueryBuilders.fieldQuery(Product.Fields.keyword, keyword).boost(6.0f));
		boolQuery.should(QueryBuilders.inQuery(Fields.vipStatus, "1", "7").boost(10.5f));
		// 过滤没有图片的数据
		BoolFilterBuilder filter = FilterBuilders.boolFilter().mustNot(
				FilterBuilders.termFilter(Product.Fields.thumbImg, ""));
		
		List<Product> productList = null;

		try {
			productList = this.productService.search(boolQuery, filter, 0, 9);
			log.info("get productList success! —— size：" + productList.size());
		} catch (Exception e) {
			log.error("get productList fail ! ", e);
		}

		if (productList == null || productList.size() == 0) {		
			log.error("get productList is null ! ");
			return this.setMsg(fromUserName, toUserName);
		}

		List<Article> articleList = new ArrayList<Article>();
		String respMessage = null;
		Article article = null;
		for (Product product : productList) {
			article = new Article();
			article.setTitle(product.getTitle());
			article.setDescription(product.getIntro());
			article.setPicUrl(product.getThumbImg());
			String redirectUrl = "http://m.youboy.com/p" + product.getId() + ".html";
			String url = this.setCallBackUrl(fromUserName, redirectUrl);
			article.setUrl(url);
			articleList.add(article);
		}

		article = new Article();
		article.setTitle("查看更多");
		article.setDescription("想要查看更多内容，请点击链接！");
		// 将图片置为空
		article.setPicUrl("");
		String redirectUrl = "http://m.youboy.com/p?q=" + URLEncoder.encode(keyword, "utf-8");
		
		String url = this.setCallBackUrl(fromUserName, redirectUrl);
		article.setUrl(url);
		articleList.add(article);

		// 创建图文消息
		NewsMessage newsMessage = new NewsMessage();
		newsMessage.setToUserName(fromUserName);
		newsMessage.setFromUserName(toUserName);
		newsMessage.setCreateTime(new Date().getTime());
		newsMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_NEWS);
		// newsMessage.setFuncFlag(0);
		newsMessage.setArticleCount(articleList.size());
		newsMessage.setArticles(articleList);

		respMessage = MessageUtil.newsMessageToXml(newsMessage);

		//保存搜索信息
		this.saveSearchInfo(SearchType.PRODUCT, fromUserName, content, keyword);
		
		return respMessage;
	}
	
	
	private String setCallBackUrl(String openid, String redirectUrl) throws UnsupportedEncodingException{
		StringBuilder url = new StringBuilder();
		url.append(wechatapiUrl).append("/help/callBack?openid=").append(openid)
				.append("&redirect_url=").append(URLEncoder.encode(redirectUrl, "utf-8"));
		return url.toString();
	}

	/**
	 * 获取公司信息
	 * 
	 * @param fromUserName
	 * @param toUserName
	 * @param content
	 * @return
	 * @throws UnsupportedEncodingException 
	 */
	private String getCompanyInfo(String fromUserName, String toUserName,
			String key, String content) throws UnsupportedEncodingException {
		//过滤特殊符号
		content = TextFilter.StringFilter(content);
				
		String keyword = content.replaceFirst(key, "").trim();
		// 过滤关键词
		keyword = kwf.filter_out(keyword, "0", keyword);

		if (StringUtils.isBlank(keyword)) {
			log.error("key word is null! ");
			return this.setMsg(fromUserName, toUserName);
		}

		BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
		// 根据关键词获取
		boolQuery.must(QueryBuilders.fieldQuery(Company.Fields.name,"\""+keyword+"\"").boost(20.4f));
		// 过滤没有图片的数据
		BoolFilterBuilder filter = FilterBuilders.boolFilter()
				.must(FilterBuilders.termFilter(Company.Fields.status, 0))
				.mustNot(FilterBuilders.termFilter(Company.Fields.logo, ""));

		List<Company> companyList = null;

		try {
			companyList = this.companyService.search(boolQuery, filter, 0, 9);
			log.info("get companyList success! —— size：" + companyList.size());
		} catch (Exception e) {
			log.error("get companyList fail ! ", e);
		}

		if (companyList == null || companyList.size() == 0) {
			log.error("get companyList is null ! ");
			return this.setMsg(fromUserName, toUserName);
		}

		List<Article> articleList = new ArrayList<Article>();
		String respMessage = null;
		Article article = null;
		for (Company company : companyList) {
			article = new Article();
			article.setTitle(company.getName());
			article.setDescription(company.getIntro());

			article.setPicUrl(company.getLogo());
			//article.setUrl("http://m.youboy.com/c" + company.getUid() + ".html");
			String redirectUrl = "http://m.youboy.com/c" + company.getUid() + ".html";
			String url = this.setCallBackUrl(fromUserName, redirectUrl);
			article.setUrl(url);
			articleList.add(article);
		}

		article = new Article();
		article.setTitle("查看更多");
		article.setDescription("想要查看更多内容，请点击链接！");
		// 将图片置为空
		article.setPicUrl("");
		String redirectUrl = "http://m.youboy.com/c?q=" + URLEncoder.encode(keyword, "utf-8");
		String url = this.setCallBackUrl(fromUserName, redirectUrl);
		article.setUrl(url);
		//article.setUrl("http://m.youboy.com/c?q=" + URLEncoder.encode(content, "utf-8"));
		
		//保存搜索信息
		this.saveSearchInfo(SearchType.COMPANY, fromUserName, content, keyword);
		articleList.add(article);

		// 创建图文消息
		NewsMessage newsMessage = new NewsMessage();
		newsMessage.setToUserName(fromUserName);
		newsMessage.setFromUserName(toUserName);
		newsMessage.setCreateTime(new Date().getTime());
		newsMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_NEWS);
		// newsMessage.setFuncFlag(0);
		newsMessage.setArticleCount(articleList.size());
		newsMessage.setArticles(articleList);

		respMessage = MessageUtil.newsMessageToXml(newsMessage);
		return respMessage;
	}

	
	/**
	 * 保存搜索信息
	 */
	private void saveSearchInfo(SearchType type, String openid, String content, String keyword){
		SearchInfo search = new SearchInfo(type, openid, content, keyword);
		try {
			searchRepository.save(search);
		} catch (Exception e) {
			log.error("[type:" + type.value() + "][openid:" + openid + "][content:" + content + "] save searchInfo error !", e);
		}
	}
	
	
}
